#pragma once

#include "../public/constants.hpp"
#include "../public/exception.hpp"

#include <string>
using std::string;

namespace bla {
	const _baseSizeType _HASHMOD = 1000000007;
	const _baseSizeType _HASHPOLX = 7;

	template<typename _Type>
	struct _defhashFunctor {
		_baseSizeType operator() () {
			throw bla::baseException("not implemented");
			return 0;
		}
	};

	/*
	 * the following _defhashs are specified function template
	  // * shall use one of inline/extern/static!//????
	 */

	template<>
	struct _defhashFunctor<unsigned long long> {
		_baseSizeType operator() (unsigned long long t) { return t; }
	};
	template<>
	struct _defhashFunctor<long long> {
		_baseSizeType operator() (long long t) { return t; }
	};
	template<>
	struct _defhashFunctor<unsigned int> {
		_baseSizeType operator() (unsigned int t) { return t; }
	};
	template<>
	struct _defhashFunctor<int> {
		_baseSizeType operator() (int t) { return t; }
	};

	template<>
	struct _defhashFunctor<unsigned long> {
		_baseSizeType operator() (unsigned long t) { return t; }
	};
	template<>
	struct _defhashFunctor<long> {
		_baseSizeType operator() (long t) { return t; }
	};
	template<>
	struct _defhashFunctor<unsigned short> {
		_baseSizeType operator() (unsigned short t) { return t; }
	};
	template<>
	struct _defhashFunctor<short> {
		_baseSizeType operator() (short t) { return t; }
	};
	template<>
	struct _defhashFunctor<unsigned char> {
		_baseSizeType operator() (unsigned char t) { return t; }
	};
	template<>
	struct _defhashFunctor<char> {
		_baseSizeType operator() (char t) { return t; }
	};
	template<>
	struct _defhashFunctor<std::string> {
		_baseSizeType operator() (std::string t) {
			_baseSizeType res = 0;
			_baseSizeType prex = _HASHPOLX;
			for (const auto& itert : t)
			{
				res += (_baseSizeType)itert * prex;
				prex *= _HASHPOLX;
			}
			return res;
		}
	};
}
